#!/usr/bin/perl -w
use strict;
use Getopt::Long;
use lib "/net/cpp-group/Leo/bin";
use parse_fasta;
#88888888888888888888888888888888888888888888888888888888888888888888888888888888

#   Usage

#88888888888888888888888888888888888888888888888888888888888888888888888888888888
my $usage = <<"USAGE";

USAGE:

    translate_by_codon.pl cdna.fa [--help]
							--cdna_output cdna.fa
							--prot_output pep.fa
							--remove_stops pep.fa
		
		This script accepts cDNA sequences and does codon by codon translations
		Unknown codons are translated as 'X'

USAGE

#88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888

#   Get options

#88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
# mandatory


# optional parameters
my $help = undef;
my ($prot_output, $cdna_output);
GetOptions('help' => \$help,
		'prot_output=s' => \$prot_output,
		'cdna_output=s' => \$cdna_output);

die $usage if ($help);
die $usage unless ($prot_output && $cdna_output);
open PROT, ">$prot_output"
	or die "Error\n\tCould not open $prot_output.\n$!";
open CDNA, ">$cdna_output"
	or die "Error\n\tCould not open $cdna_output.\n$!";


my %aa_nucl_map;
my %stops;
@stops{qw(TGA TAA TAG)} = ();
sub to_aa($)
{
	return (exists ($aa_nucl_map{$_[0]}) ? $aa_nucl_map{$_[0]} : 'X');
}




sub create_aa_nucl_map()
{
	$aa_nucl_map{'GCA'} = 'A';
	$aa_nucl_map{'GCC'} = 'A';
	$aa_nucl_map{'GCG'} = 'A';
	$aa_nucl_map{'GCT'} = 'A';
	$aa_nucl_map{'GCX'} = 'A';
	$aa_nucl_map{'GCN'} = 'A';
	$aa_nucl_map{'GC-'} = 'A';
	
	$aa_nucl_map{'TGC'} = 'C';
	$aa_nucl_map{'TGT'} = 'C';
	$aa_nucl_map{'TGT'} = 'C';
	$aa_nucl_map{'TGY'} = 'C';
	
	$aa_nucl_map{'GAC'} = 'D';
	$aa_nucl_map{'GAT'} = 'D';
	$aa_nucl_map{'GAY'} = 'D';
	
	$aa_nucl_map{'GAA'} = 'E';
	$aa_nucl_map{'GAG'} = 'E';
	$aa_nucl_map{'GAR'} = 'E';
	
	$aa_nucl_map{'TTC'} = 'F';
	$aa_nucl_map{'TTT'} = 'F';
	$aa_nucl_map{'TTY'} = 'F';
	
	$aa_nucl_map{'GGA'} = 'G';
	$aa_nucl_map{'GGC'} = 'G';
	$aa_nucl_map{'GGG'} = 'G';
	$aa_nucl_map{'GGT'} = 'G';
	$aa_nucl_map{'GGN'} = 'G';
	$aa_nucl_map{'GGX'} = 'G';
	$aa_nucl_map{'GG-'} = 'G';
	
	$aa_nucl_map{'CAC'} = 'H';
	$aa_nucl_map{'CAT'} = 'H';
	$aa_nucl_map{'CAY'} = 'H';
	
	$aa_nucl_map{'ATA'} = 'I';
	$aa_nucl_map{'ATC'} = 'I';
	$aa_nucl_map{'ATT'} = 'I';
	$aa_nucl_map{'ATH'} = 'I';
	
	$aa_nucl_map{'AAA'} = 'K';
	$aa_nucl_map{'AAG'} = 'K';
	$aa_nucl_map{'AAG'} = 'K';
	
	$aa_nucl_map{'TTA'} = 'L';
	$aa_nucl_map{'TTG'} = 'L';
	$aa_nucl_map{'CTA'} = 'L';
	$aa_nucl_map{'CTC'} = 'L';
	$aa_nucl_map{'CTG'} = 'L';
	$aa_nucl_map{'CTT'} = 'L';
	
	$aa_nucl_map{'TTR'} = 'L';
	$aa_nucl_map{'YTR'} = 'L';
	$aa_nucl_map{'CT-'} = 'L';
	$aa_nucl_map{'YT-'} = 'L';
	$aa_nucl_map{'CTN'} = 'L';
	$aa_nucl_map{'YTN'} = 'L';
	$aa_nucl_map{'CTX'} = 'L';
	$aa_nucl_map{'YTX'} = 'L';

	$aa_nucl_map{'ATG'} = 'M';
	
	$aa_nucl_map{'AAC'} = 'N';
	$aa_nucl_map{'AAT'} = 'N';
	$aa_nucl_map{'AAY'} = 'N';

	$aa_nucl_map{'CCA'} = 'P';
	$aa_nucl_map{'CCC'} = 'P';
	$aa_nucl_map{'CCG'} = 'P';
	$aa_nucl_map{'CCT'} = 'P';

	$aa_nucl_map{'CC-'} = 'P';
	$aa_nucl_map{'CCN'} = 'P';
	$aa_nucl_map{'CCX'} = 'P';

	$aa_nucl_map{'CAA'} = 'Q';
	$aa_nucl_map{'CAG'} = 'Q';
	$aa_nucl_map{'CAR'} = 'Q';
	
	
	$aa_nucl_map{'CGA'} = 'R';
	$aa_nucl_map{'CGC'} = 'R';
	$aa_nucl_map{'CGG'} = 'R';
	$aa_nucl_map{'CGT'} = 'R';
	$aa_nucl_map{'AGA'} = 'R';
	$aa_nucl_map{'AGG'} = 'R';
	$aa_nucl_map{'AGR'} = 'R';
	$aa_nucl_map{'MGR'} = 'R';
	$aa_nucl_map{'CGX'} = 'R';
	$aa_nucl_map{'MGX'} = 'R';
	$aa_nucl_map{'CG-'} = 'R';
	$aa_nucl_map{'MG-'} = 'R';
	$aa_nucl_map{'CGN'} = 'R';
	$aa_nucl_map{'MGN'} = 'R';
	
	
	
	$aa_nucl_map{'TCA'} = 'S';
	$aa_nucl_map{'TCC'} = 'S';
	$aa_nucl_map{'TCG'} = 'S';
	$aa_nucl_map{'TCT'} = 'S';
	$aa_nucl_map{'AGC'} = 'S';
	$aa_nucl_map{'AGT'} = 'S';
	$aa_nucl_map{'AGY'} = 'S';
	$aa_nucl_map{'TCX'} = 'S';
	$aa_nucl_map{'WSX'} = 'S';
	$aa_nucl_map{'TC-'} = 'S';
	$aa_nucl_map{'WS-'} = 'S';
	$aa_nucl_map{'TCN'} = 'S';
	$aa_nucl_map{'WSN'} = 'S';
	
	$aa_nucl_map{'ACA'} = 'T';
	$aa_nucl_map{'ACC'} = 'T';
	$aa_nucl_map{'ACG'} = 'T';
	$aa_nucl_map{'ACT'} = 'T';
	$aa_nucl_map{'ACX'} = 'T';
	$aa_nucl_map{'AC-'} = 'T';
	$aa_nucl_map{'ACN'} = 'T';
	
	$aa_nucl_map{'GTA'} = 'V';
	$aa_nucl_map{'GTC'} = 'V';
	$aa_nucl_map{'GTG'} = 'V';
	$aa_nucl_map{'GTT'} = 'V';
	$aa_nucl_map{'GTX'} = 'V';
	$aa_nucl_map{'GT-'} = 'V';
	$aa_nucl_map{'GTN'} = 'V';
	
	$aa_nucl_map{'TGG'} = 'W';
	
	$aa_nucl_map{'TAC'} = 'Y';
	$aa_nucl_map{'TAT'} = 'Y';
	$aa_nucl_map{'TAY'} = 'Y';
}



#_________________________________________________________________________________________

#   translate_callback
#                       $annotation     annotation line
#                       \@sequence      sequence lines
#                       $line count     line count in file
#                       $acc_pos        accession line file position
#                       $sequence_count index of current sequence
#                       $data           see below

#_________________________________________________________________________________________
sub translate_callback($$$$$$)
{
    my ($acc,  $sequences, $acc_pos, $sequence_count) = @_[0, 1, 3, 4];

	my $seq = join ("", @$sequences);
	print STDERR "." if ($sequence_count % 100 == 0);
	die "Error\n\t$acc on line [$acc_pos] does not have an integral number of codons\n"
			unless (length($seq) % 3 == 0);
#	my @cdna = split (//, $seq);
	$seq =~ tr/\-/N/;
	my @list = unpack(("a3") x (length($seq) / 3), $seq);
	print PROT ">$acc";
	print CDNA ">$acc\n";
	my $len = @list;
	for (my $i = 0; $i < $len; ++$i)
	{
		print PROT "\n" if ($i % 60 == 0);
		if (!exists $stops{$list[$i]})
		{
			print PROT to_aa($list[$i]);
			print CDNA $list[$i];
		}
		else
		{
			print PROT 'X';
			print CDNA 'NNN';
		}
	}
	print PROT "\n";
	print CDNA "\n";

	
#	print STDERR join ("\n", @list), "\n";
#	exit (1);
#	for (my $i = 0; $i < @cdna; $i += 3)
#	{
#		to_aa{$cdna[$i]}
#	}
}


create_aa_nucl_map();

unshift(@ARGV, '-') unless @ARGV;
while (my $ARGV = shift @ARGV)
{
	unless (open (ARGV, $ARGV))
	{
		warn "Can't open $ARGV:$!\n";
		next;
	}
	print STDERR "Translating:\n\t[";
	my $cnt_seq =parse_fasta::parse_sequences(  *ARGV,
												\&translate_callback,
												undef);
	close ARGV;
	print STDERR "]\nFinished!\n";

}








